<template>
  <div class="snake-container">
    <div id="snake-game"></div>
    <div class="game-info">
      <div class="score-panel">
        <h3>分数: {{ score }}</h3>
        <h3>等级: {{ level }}</h3>
      </div>
      <div class="controls">
        <button @click="startGame" :disabled="gameStarted && !gameOver">{{ gameOver ? "重新开始" : "开始游戏" }}</button>
        <button @click="pauseGame" :disabled="!gameStarted || gameOver">{{ paused ? "继续" : "暂停" }}</button>
      </div>
      <div class="instructions">
        <h3>操作说明</h3>
        <p>← → ↑ ↓ : 控制蛇的方向</p>
        <p>P : 暂停/继续游戏</p>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import Phaser from "phaser";

export default {
  name: "SnakeGame",
  setup() {
    const score = ref(0);
    const level = ref(1);
    const gameStarted = ref(false);
    const paused = ref(false);
    const gameOver = ref(false);

    let game = null;
    let mainScene = null;

    // 贪吃蛇游戏主场景
    class SnakeScene extends Phaser.Scene {
      snake: Phaser.GameObjects.Graphics[] | null;
      food: Phaser.GameObjects.Graphics | null;
      cursors: Phaser.Types.Input.Keyboard.CursorKeys | null;
      speed: number;
      moveTime: number;
      direction: string;
      nextDirection: string;
      gridSize: number;
      gameWidth: number;
      gameHeight: number;
      gameStarted: boolean;
      paused: boolean;
      gameOver: boolean;

      constructor() {
        super("SnakeScene");
        this.snake = null;
        this.food = null;
        this.cursors = null;
        this.speed = 100;
        this.moveTime = 0;
        this.direction = 'right';
        this.nextDirection = 'right';
        this.gridSize = 20; // 网格大小
        this.gameWidth = 600;
        this.gameHeight = 600;
        this.gameStarted = false;
        this.paused = false;
        this.gameOver = false;
      }

      preload() {
        // 不再需要加载图像，我们将使用Phaser的图形API直接绘制
      }

      create() {
        // 创建蛇和食物
        this.snake = [];
        
        // 获取中心位置
        const safeX = Math.floor(this.gameWidth / (2 * this.gridSize)) * this.gridSize;
        const safeY = Math.floor(this.gameHeight / (2 * this.gridSize)) * this.gridSize;
        
        // 蛇的初始方向设置为向右
        this.direction = 'right';
        this.nextDirection = 'right';
        
        // 创建蛇头（使用图形API绘制）
        const head = this.add.graphics();
        this.drawSnakeHead(head, 'right');
        head.x = safeX;
        head.y = safeY;
        this.snake.push(head);
        
        // 创建蛇身（2节）- 确保它们紧接着向左排列
        for (let i = 1; i < 3; i++) {
          const segment = this.add.graphics();
          this.drawSnakeBody(segment);
          segment.x = safeX - i * this.gridSize;
          segment.y = safeY;
          this.snake.push(segment);
        }

        // 创建食物
        this.food = this.add.graphics();
        this.drawFood(this.food);
        
        // 初始化时先将食物放在场景之外并隐藏
        this.food.setVisible(false);
        this.food.x = -100;
        this.food.y = -100;
        
        // 添加食物闪烁动画
        this.tweens.add({
          targets: this.food,
          alpha: 0.7,
          duration: 500,
          ease: 'Sine.easeInOut',
          yoyo: true,
          repeat: -1
        });
        
        // 设置键盘控制
        this.cursors = this.input.keyboard.createCursorKeys();
        
        // 添加游戏区域边界可视化
        const graphics = this.add.graphics();
        graphics.lineStyle(2, 0x4CAF50, 1);
        // 使用游戏区域的大小绘制边框，略微向内缩一点
        graphics.strokeRect(1, 1, this.gameWidth - 2, this.gameHeight - 2);
        
        // 添加网格背景，确保网格线清晰可见
        const gridGraphics = this.add.graphics();
        gridGraphics.lineStyle(0.5, 0x222222, 0.3);
        
        // 确保网格线覆盖整个游戏区域
        for (let x = 0; x <= this.gameWidth; x += this.gridSize) {
          gridGraphics.moveTo(x, 0);
          gridGraphics.lineTo(x, this.gameHeight);
        }
        
        for (let y = 0; y <= this.gameHeight; y += this.gridSize) {
          gridGraphics.moveTo(0, y);
          gridGraphics.lineTo(this.gameWidth, y);
        }
        
        // 确保绘制命令执行
        gridGraphics.strokePath();
        
        // 确保游戏不会自动开始，需要点击"开始游戏"按钮
        this.gameStarted = false;
        
        // 初始蛇的位置确保不在屏幕边缘，防止一开始就检测到碰撞
        for (let i = 0; i < this.snake.length; i++) {
          this.snake[i].x = safeX - i * this.gridSize;
          this.snake[i].y = safeY;
        }
      }

      update(time) {
        // 如果游戏暂停或未开始或已结束，不进行更新
        if (this.gameOver || !this.gameStarted || this.paused) {
          return;
        }

        // 处理方向输入
        if (this.cursors.left.isDown && this.direction !== 'right') {
          this.nextDirection = 'left';
        } else if (this.cursors.right.isDown && this.direction !== 'left') {
          this.nextDirection = 'right';
        } else if (this.cursors.up.isDown && this.direction !== 'down') {
          this.nextDirection = 'up';
        } else if (this.cursors.down.isDown && this.direction !== 'up') {
          this.nextDirection = 'down';
        }

        // 仅在游戏已开始时才移动蛇
        if (time >= this.moveTime) {
          return this.moveSnake(time);
        }
      }

      moveSnake(time) {
        // 更新移动时间
        this.moveTime = time + Math.max(50, 200 - (level.value - 1) * 10);
        
        // 应用下一个方向
        this.direction = this.nextDirection;
        
        // 计算下一个头部位置 - 确保网格对齐
        let x = this.snake[0].x;
        let y = this.snake[0].y;
        
        switch (this.direction) {
          case 'left':
            x -= this.gridSize;
            break;
          case 'right':
            x += this.gridSize;
            break;
          case 'up':
            y -= this.gridSize;
            break;
          case 'down':
            y += this.gridSize;
            break;
        }
        
        // 检查是否撞到边界
        if (x < 0 || y < 0 || x >= this.gameWidth || y >= this.gameHeight) {
          return this.gameOverHandler();
        }
        
        // 检查是否撞到自己
        for (let i = 1; i < this.snake.length; i++) {
          if (this.snake[i].x === x && this.snake[i].y === y) {
            return this.gameOverHandler();
          }
        }
        
        // 检查是否吃到食物
        let ate = false;
        if (this.food.x === x && this.food.y === y) {
          ate = true;
          score.value += 10;
          
          // 每100分升一级
          if (score.value % 100 === 0) {
            level.value++;
          }
          
          // 吃到食物时的视觉反馈
          this.createFoodEffect(x, y);
          
          this.repositionFood();
        }
        
        // 1. 移动蛇身（从尾到头，每一节都精确跟随前一节）
        for (let i = this.snake.length - 1; i > 0; i--) {
          // 确保严格对齐到网格
          this.snake[i].x = this.snake[i - 1].x;
          this.snake[i].y = this.snake[i - 1].y;
        }
        
        // 2. 移动蛇头到新位置 - 确保网格对齐
        this.snake[0].x = x;
        this.snake[0].y = y;
        
        // 3. 更新蛇头的图像以匹配方向
        this.updateHeadTexture(this.snake[0], this.direction);
        
        // 4. 如果吃到食物，添加新的身体段
        if (ate) {
          // 计算新段的位置（默认放在与最后一节相同的位置，视觉上不会立即看到）
          const lastSegment = this.snake[this.snake.length - 1];
          const newSegment = this.add.graphics();
          this.drawSnakeBody(newSegment);
          newSegment.x = lastSegment.x;
          newSegment.y = lastSegment.y;
          
          // 添加到蛇的数组中
          this.snake.push(newSegment);
        }
        
        return true;
      }

      repositionFood() {
        // 确保食物不会出现在边界位置或蛇身上
        const gridWidth = Math.floor(this.gameWidth / this.gridSize) - 1;
        const gridHeight = Math.floor(this.gameHeight / this.gridSize) - 1;
        
        // 创建所有可能的位置，排除靠近边缘的位置
        const availablePositions = [];
        
        for (let x = 1; x < gridWidth; x++) {
          for (let y = 1; y < gridHeight; y++) {
            const posX = x * this.gridSize;
            const posY = y * this.gridSize;
            
            // 检查该位置是否被蛇身占用
            let available = true;
            for (const segment of this.snake) {
              if (segment.x === posX && segment.y === posY) {
                available = false;
                break;
              }
            }
            
            if (available) {
              availablePositions.push({ x: posX, y: posY });
            }
          }
        }
        
        // 随机选择一个位置
        if (availablePositions.length > 0) {
          // 使用固定种子的随机数，确保每次游戏开始时食物位置相同
          const seed = String(score.value + (level.value * 100));
          const rnd = new Phaser.Math.RandomDataGenerator([seed]);
          const index = Math.floor(rnd.frac() * availablePositions.length);
          const pos = availablePositions[index];
          
          // 确保食物显示
          this.food.setVisible(true); 
          this.food.x = pos.x;
          this.food.y = pos.y;
          console.log("食物位置:", pos.x, pos.y, "分数:", score.value);
        } else {
          // 如果没有可用位置(极少情况)，放在一个默认位置
          const defaultX = Math.floor(this.gameWidth / this.gridSize / 2) * this.gridSize;
          const defaultY = Math.floor(this.gameHeight / this.gridSize / 2) * this.gridSize;
          this.food.setVisible(true);
          this.food.x = defaultX;
          this.food.y = defaultY;
        }
      }

      gameOverHandler() {
        this.gameOver = true;
        gameOver.value = true;
        gameStarted.value = false;
        
        // 创建游戏结束提示
        const textStyle = {
          font: 'bold 32px Arial',
          fill: '#ffffff',
          stroke: '#000000',
          strokeThickness: 6,
          align: 'center'
        };
        
        this.add.text(this.gameWidth / 2, this.gameHeight / 2, '游戏结束', textStyle).setOrigin(0.5);
        this.add.text(this.gameWidth / 2, this.gameHeight / 2 + 50, `最终得分: ${score.value}`, textStyle).setOrigin(0.5);
        
        return false;
      }

      // 使用图形API绘制蛇头
      drawSnakeHead(graphics, direction) {
        graphics.clear();
        
        // 蛇头主体 - 绿色矩形
        graphics.fillStyle(0x00aa00, 1);
        graphics.fillRect(0, 0, this.gridSize, this.gridSize);
        
        // 蛇头边框 - 深绿色
        graphics.lineStyle(2, 0x008800, 1);
        graphics.strokeRect(0, 0, this.gridSize, this.gridSize);
        
        // 蛇头眼睛 - 白色圆形
        graphics.fillStyle(0xffffff, 1);
        
        // 根据方向设置眼睛位置
        switch (direction) {
          case 'up':
            // 两个眼睛在上方
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.25, this.gridSize * 0.15);
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.25, this.gridSize * 0.15);
            break;
          case 'down':
            // 两个眼睛在下方
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.75, this.gridSize * 0.15);
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.75, this.gridSize * 0.15);
            break;
          case 'left':
            // 两个眼睛在左侧
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.25, this.gridSize * 0.15);
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.75, this.gridSize * 0.15);
            break;
          case 'right':
            // 两个眼睛在右侧
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.25, this.gridSize * 0.15);
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.75, this.gridSize * 0.15);
            break;
        }
        
        // 眼睛瞳孔 - 黑色圆形
        graphics.fillStyle(0x000000, 1);
        switch (direction) {
          case 'up':
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.25, this.gridSize * 0.05);
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.25, this.gridSize * 0.05);
            break;
          case 'down':
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.75, this.gridSize * 0.05);
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.75, this.gridSize * 0.05);
            break;
          case 'left':
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.25, this.gridSize * 0.05);
            graphics.fillCircle(this.gridSize * 0.25, this.gridSize * 0.75, this.gridSize * 0.05);
            break;
          case 'right':
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.25, this.gridSize * 0.05);
            graphics.fillCircle(this.gridSize * 0.75, this.gridSize * 0.75, this.gridSize * 0.05);
            break;
        }
      }

      // 绘制蛇身体
      drawSnakeBody(graphics) {
        graphics.clear();
        
        // 蛇身主体 - 浅绿色
        graphics.fillStyle(0x00cc00, 1);
        graphics.fillRect(1, 1, this.gridSize - 2, this.gridSize - 2);
        
        // 蛇身边框
        graphics.lineStyle(1, 0x008800, 1);
        graphics.strokeRect(1, 1, this.gridSize - 2, this.gridSize - 2);
      }

      // 绘制食物
      drawFood(graphics) {
        graphics.clear();
        
        // 食物主体 - 红色
        graphics.fillStyle(0xff0000, 1);
        graphics.fillRect(2, 2, this.gridSize - 4, this.gridSize - 4);
        
        // 食物高光 - 给一个立体感
        graphics.fillStyle(0xff6666, 1);
        graphics.fillRect(3, 3, this.gridSize / 2 - 2, this.gridSize / 2 - 2);
      }

      // 使用不同的图形绘制来表示蛇头方向
      updateHeadTexture(head, direction) {
        this.drawSnakeHead(head, direction);
      }

      // 创建简单的食物吃到效果
      createFoodEffect(x, y) {
        // 创建一个圆形效果
        const circle = this.add.circle(
          x + this.gridSize / 2, 
          y + this.gridSize / 2, 
          this.gridSize / 2, 
          0xffcc00, 
          0.8
        );
        
        // 添加动画
        this.tweens.add({
          targets: circle,
          scaleX: 2,
          scaleY: 2,
          alpha: 0,
          duration: 300,
          onComplete: () => {
            circle.destroy();
          }
        });
      }
    }

    // 全局引用暂停函数，供场景内部调用
    let outsidePauseGame;
    
    // 跟踪上次暂停/继续切换时间
    let lastToggleTime = 0;
    
    // 暂停/继续游戏
    const pauseGame = () => {
      // 防止频繁切换，添加300ms的冷却时间
      const now = Date.now();
      if (now - lastToggleTime < 300) {
        console.log("暂停/继续切换过快，忽略");
        return;
      }
      lastToggleTime = now;
      
      console.log("pauseGame被调用，当前暂停状态:", paused.value);
      
      if (game && gameStarted.value && !gameOver.value) {
        // 切换暂停状态
        paused.value = !paused.value;
        console.log("暂停状态切换为:", paused.value);
        
        if (mainScene) {
          mainScene.paused = paused.value;
          
          try {
            if (paused.value) {
              console.log("游戏暂停中...");
              // 使用更明确的方式暂停
              game.scene.getScene("SnakeScene").scene.pause();
            } else {
              console.log("游戏继续中...");
              // 使用更明确的方式继续
              game.scene.getScene("SnakeScene").scene.resume();
            }
          } catch (error) {
            console.error("暂停/继续游戏时出错:", error);
            // 备用方案
            if (paused.value) {
              game.scene.pause("SnakeScene");
            } else {
              game.scene.resume("SnakeScene");
            }
          }
        }
      }
    };
    
    // 设置全局引用
    outsidePauseGame = pauseGame;

    // 使用DOM级别的事件监听P键，不依赖于Phaser的update
    let lastPressTime = 0; // 防止快速连续按P
    function handleKeyPress(event) {
      if (event.key === 'p' || event.key === 'P') {
        // 防止快速连续按键，添加300ms的冷却时间
        const now = Date.now();
        if (now - lastPressTime < 300) {
          console.log("P键按下过快，忽略");
          return;
        }
        lastPressTime = now;
        
        console.log("P键被按下 - 从DOM事件中检测到");
        if (gameStarted.value && !gameOver.value) {
          pauseGame();
        }
      }
    }

    // 开始游戏
    const startGame = () => {
      // 重置游戏状态
      score.value = 0;
      level.value = 1;
      gameStarted.value = true;
      paused.value = false;
      gameOver.value = false;
      
      // 重新启动场景并确保所有状态正确同步
      if (game && mainScene) {
        mainScene.scene.restart();
        
        // 使用setTimeout确保在场景重新创建后再设置状态
        setTimeout(() => {
          if (mainScene) {
            // 设置游戏基本状态
            mainScene.gameStarted = true;
            mainScene.paused = false;
            mainScene.gameOver = false;
            mainScene.direction = 'right';
            mainScene.nextDirection = 'right';
            
            // 确保蛇头显示为向右移动
            if (mainScene.snake && mainScene.snake.length > 0) {
              mainScene.updateHeadTexture(mainScene.snake[0], 'right');
            }
            
            // 游戏开始后才显示并定位食物
            if (mainScene.food) {
              // 游戏刚开始时，固定食物位置在较远处
              const farX = Math.floor(mainScene.gameWidth / mainScene.gridSize * 0.7) * mainScene.gridSize;
              const farY = Math.floor(mainScene.gameHeight / mainScene.gridSize * 0.7) * mainScene.gridSize;
              
              mainScene.food.setVisible(true);
              mainScene.food.x = farX;
              mainScene.food.y = farY;
              
              console.log("游戏开始，食物位置已设置:", farX, farY);
            }
          }
        }, 100);
      }
    };

    onMounted(() => {
      // 添加全局键盘事件监听器
      window.addEventListener('keydown', handleKeyPress);
      
      // 游戏配置
      const config = {
        type: Phaser.AUTO,
        width: 600,
        height: 600,
        parent: "snake-game",
        scene: [SnakeScene],
        backgroundColor: "#e9f5e9", 
        render: {
          pixelArt: true,
          antialias: false,
          // 关闭圆整像素，避免网格线消失
          roundPixels: false,
          // 确保canvas元素无边框和内边距
          clearBeforeRender: true,
          premultipliedAlpha: false
        }
      };
      
      // 创建游戏实例
      game = new Phaser.Game(config);
      
      // 获取场景引用
      game.events.on("ready", () => {
        mainScene = game.scene.getScene("SnakeScene");
      });
    });

    onUnmounted(() => {
      // 移除事件监听器，防止内存泄漏
      window.removeEventListener('keydown', handleKeyPress);
      
      // 销毁游戏实例
      if (game) {
        game.destroy(true);
      }
    });

    return {
      score,
      level,
      gameStarted,
      paused,
      gameOver,
      startGame,
      pauseGame
    };
  }
};
</script>

<style lang="scss" src="./snake.scss" scoped></style>